package examples;



import java.util.Collection;
import java.util.LinkedList;

import facade.UserFacade;
import facade.associationclasses.AssociationClassFacade;
import facade.kernel.AssociationFacade;
import facade.kernel.DataTypeFacade;
import facade.kernel.EnumerationFacade;
import facade.kernel.EnumerationLiteralFacade;
import facade.kernel.GeneralizationFacade;
import facade.kernel.LiteralIntegerFacade;
import facade.kernel.PropertyFacade;
import facade.kernel.UmlClassFacade;
import facade.ocl.CollectionItemFacade;
import facadeOCL.ParserFacade;
import project.Project;
import uml2.associationclasses.AssociationClass;
import uml2.kernel.Association;
import uml2.kernel.DataType;
import uml2.kernel.Enumeration;
import uml2.kernel.EnumerationLiteral;
import uml2.kernel.LiteralInteger;
import uml2.kernel.Property;
import uml2.kernel.UmlClass;
import uml2.kernel.VisibilityKindEnum;
import uml2.ocl2.CollectionItem;
import XMIConverter.ConverterToEinaGMC;
import XMIConverter.ConverterToPoseidon;


public class PoseidonToEina {
	public static void main (String args[]) throws Exception {
		ConverterToEinaGMC ctgmc = new ConverterToEinaGMC();
		ctgmc.convert("/Users/lotendil/Desktop/dblp.xmi", "/Users/lotendil/Desktop/dblpeina.xmi", "Poseidon");
		System.out.println("FET PSDN -> GMC");
		
		//makeModel();
		
	    //prova();
		
		/*ConverterToPoseidon ctp = new ConverterToPoseidon();
		ctp.convert("/Users/lotendil/Desktop/models/pose.xmi", "/Users/lotendil/Desktop/models/posP.xmi", "GMC");
		System.out.println("FET GMC -> PSDN");*/
		//creaTernaria();
		//creaEnum();
		
		/*Project p = new Project();
		p.importXMI("/Users/lotendil/Desktop/models/borrar.xmi");
		ParserFacade pf = new ParserFacade();
		pf.deleteOclExpression("c1", p);
		p.saveXMI("/Users/lotendil/Desktop/models/borrar.xmi");
		p.closeProject();*/
		System.out.println("FI");
	}

	public static void prova() throws Exception {
		Project p = new Project("aaa");
		CollectionItemFacade cif = new CollectionItemFacade(p);
		CollectionItem ci = cif.createCollectionItem();
		DataTypeFacade dtf = new DataTypeFacade(p);
		DataType integer = dtf.createDataType();
		integer.setName("Integer");
		ci.setType(integer); // falla aqui
	}
	
	public static void creaEnum() throws Exception {
		Project p = new Project();
		p.importXMI("/Users/lotendil/Desktop/models/final.xmi");
		
		EnumerationFacade ef = new EnumerationFacade(p);
		Enumeration e = ef.createEnumeration();
		e.setName("Sexe");
		EnumerationLiteralFacade elf = new EnumerationLiteralFacade(p);
		EnumerationLiteral home = elf.createEnumerationLiteral();
		EnumerationLiteral dona = elf.createEnumerationLiteral();
		home.setName("home");
		dona.setName("dona");
		home.setEnumeration(e);
		dona.setEnumeration(e);
		
		PropertyFacade pf = new PropertyFacade(p);
		Property pSexe = pf.createProperty();
		pSexe.setName("sexe");
		pSexe.setType(e);
		
		UserFacade uf = new UserFacade(p);
		UmlClass persona = uf.findClassByName("Persona");
		pSexe.setUmlclass(persona);
		
		p.saveXMI("/Users/lotendil/Desktop/models/enum.xmi");
		p.closeProject();
		System.out.println("FET TOT");
	}

	public static void creaTernaria() throws Exception {
		Project p = new Project();
		p.importXMI("/Users/lotendil/Desktop/models/ceina.xmi");
		
		// Crea Clases Reunio i Projecte
		UmlClassFacade ucf = new UmlClassFacade(p);
		UmlClass Reunio = ucf.createUmlClass("Reunio", VisibilityKindEnum.PUBLIC, false, false);
		UmlClass Projecte = ucf.createUmlClass("Projecte", VisibilityKindEnum.PUBLIC, false, false);
		System.out.println("Classes Reunio i Projecte");
		
		//Property reunio
		PropertyFacade pf = new PropertyFacade(p);
		Property pReunio = pf.createProperty();
		pReunio.setName("reunio");
		pReunio.setType(Reunio);
		LiteralIntegerFacade lif = new LiteralIntegerFacade(p);
		LiteralInteger lowermultiplicity = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity = lif.createLiteralInteger();
		lowermultiplicity.setValue(0);
		lowermultiplicity.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity.setValue(-1);
		uppermultiplicity.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		pReunio.setLowerValue(lowermultiplicity);
		pReunio.setUpperValue(uppermultiplicity);
		
		//Property projecte
		Property pProjecte = pf.createProperty();
		pProjecte.setName("projecte");
		pProjecte.setType(Projecte);
		LiteralIntegerFacade lif2 = new LiteralIntegerFacade(p);
		LiteralInteger lowermultiplicity2 = lif2.createLiteralInteger();
		LiteralInteger uppermultiplicity2 = lif2.createLiteralInteger();
		lowermultiplicity2.setValue(0);
		lowermultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity2.setValue(-1);
		uppermultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		pProjecte.setLowerValue(lowermultiplicity2);
		pProjecte.setUpperValue(uppermultiplicity2);
		

		//Property templeat
		Property pTempleat = pf.createProperty();
		pTempleat.setName("templeat");
		pTempleat.setType(new UserFacade(p).findClassByName("Persona"));
		LiteralIntegerFacade lif3 = new LiteralIntegerFacade(p);
		LiteralInteger lowermultiplicity3 = lif3.createLiteralInteger();
		LiteralInteger uppermultiplicity3 = lif3.createLiteralInteger();
		lowermultiplicity3.setValue(0);
		lowermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity3.setValue(-1);
		uppermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		pTempleat.setLowerValue(lowermultiplicity3);
		pTempleat.setUpperValue(uppermultiplicity3);
		
		System.out.println("Properties");
		
		// Crea associationclass
		AssociationClassFacade af = new AssociationClassFacade(p);
		Collection c = new LinkedList();
		c.add(pReunio);
		c.add(pProjecte);
		c.add(pTempleat);
		AssociationClass ternaria = af.createAssociationClass(c);
		ternaria.setName("Assistir");
		
		System.out.println("Association 1");
		
		//Property empleats
		Property empleats = pf.createProperty();
		empleats.setName("empleats");
		empleats.setType(new UserFacade(p).findClassByName("Persona"));
		LiteralIntegerFacade lif4 = new LiteralIntegerFacade(p);
		LiteralInteger lowermultiplicity4 = lif4.createLiteralInteger();
		LiteralInteger uppermultiplicity4 = lif4.createLiteralInteger();
		lowermultiplicity4.setValue(0);
		lowermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity4.setValue(-1);
		uppermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		empleats.setLowerValue(lowermultiplicity4);
		empleats.setUpperValue(uppermultiplicity4);
		
		//Property caps
		Property caps = pf.createProperty();
		caps.setName("caps");
		caps.setType(new UserFacade(p).findClassByName("Persona"));
		LiteralIntegerFacade lif5 = new LiteralIntegerFacade(p);
		LiteralInteger lowermultiplicity5 = lif5.createLiteralInteger();
		LiteralInteger uppermultiplicity5 = lif5.createLiteralInteger();
		lowermultiplicity5.setValue(0);
		lowermultiplicity5.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity5.setValue(-1);
		uppermultiplicity5.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		caps.setLowerValue(lowermultiplicity5);
		caps.setUpperValue(uppermultiplicity5);
		
		// Crea associationclass
		Collection c1 = new LinkedList();
		c1.add(empleats);
		c1.add(caps);
		AssociationClass reflexiva = af.createAssociationClass(c1);
		reflexiva.setName("Puntuacio");
		//Property valor
		Property valor = pf.createProperty();
		valor.setName("valor");
		valor.setType(new UserFacade(p).findDataTypeByName("Integer"));
		valor.setUmlclass(reflexiva);
		
		System.out.println("Association2");
		
		p.saveXMI("/Users/lotendil/Desktop/models/final.xmi");
		System.out.println("FET TOT");
	}


	public static void makeModel() throws Exception {
		Project p = new Project();
		// Facade classes
		UmlClassFacade ucf 	= new UmlClassFacade(p);
		PropertyFacade pf 	= new PropertyFacade(p);
		DataTypeFacade dtf 	= new DataTypeFacade(p);
		LiteralIntegerFacade lif = new LiteralIntegerFacade(p);
		
		// Creation of the basic types
		DataType integer 	= dtf.createDataType();
		DataType real 		= dtf.createDataType();
		DataType booleantype= dtf.createDataType();
		DataType string 	= dtf.createDataType();
		
		integer.setName("Integer");
		real.setName("Real");
		booleantype.setName("Boolean");
		string.setName("String");
		
		
		// Creation of the UML Classes
		UmlClass person 	= ucf.createUmlClass();
		UmlClass employee 	= ucf.createUmlClass();
		UmlClass client 	= ucf.createUmlClass();
		UmlClass company 	= ucf.createUmlClass();
		UmlClass department = ucf.createUmlClass();
		
		person.setName("Person");
		employee.setName("Employee");
		client.setName("Client");
		company.setName("Company");
		department.setName("Department");
		
		// Creation of the owned attributes for the previous classes
		Property personName	 	= pf.createProperty();
		Property personAge 		= pf.createProperty();
		Property employeeSalary = pf.createProperty();
		Property clientId 		= pf.createProperty();
		Property clientIsPremium= pf.createProperty();
		Property departmentName = pf.createProperty();
			// Set name and type
		personName.setName("name");
		personName.setType(string);
		personAge.setName("age");
		personAge.setType(integer);
		employeeSalary.setName("salary");
		employeeSalary.setType(real);
		clientId.setName("idClient");
		clientId.setType(integer);
		clientIsPremium.setName("isPremium");
		clientIsPremium.setType(booleantype);
		departmentName.setName("name");
		departmentName.setType(string);
		
		// Place attributes into their owner UML class
		personName.setUmlclass(person);
		personAge.setUmlclass(person);
		employeeSalary.setUmlclass(employee);
		clientId.setUmlclass(client);
		clientIsPremium.setUmlclass(client);
		departmentName.setUmlclass(department);

		// Creation of the Person hierarchy
		GeneralizationFacade gf = new GeneralizationFacade(p);
		gf.createGeneralization(person, client);
		gf.createGeneralization(person, employee);
		
		// Create association between Company and Department
		AssociationFacade af = new AssociationFacade(p);
			// These are the association ends
		Property companyEnd = pf.createProperty();
		Property departmentEnd = pf.createProperty();
		companyEnd.setType(company);
		departmentEnd.setType(department);
			
			// Create and set the multiplicity 0..1 to Company end
		LiteralInteger lowermultiplicity = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity = lif.createLiteralInteger();
		lowermultiplicity.setValue(0);
		lowermultiplicity.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity.setValue(1);
		uppermultiplicity.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		companyEnd.setLowerValue(lowermultiplicity);
		companyEnd.setUpperValue(uppermultiplicity);
		
			// Create and set the multiplicity 0..* to Department end
		LiteralInteger lowermultiplicity2 = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity2 = lif.createLiteralInteger();
		lowermultiplicity2.setValue(0);
		lowermultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity2.setValue(-1);
		uppermultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		departmentEnd.setLowerValue(lowermultiplicity2);
		departmentEnd.setUpperValue(uppermultiplicity2);
		
		LinkedList associationEnds = new LinkedList();
		associationEnds.add(companyEnd);
		associationEnds.add(departmentEnd);
		Association companytodepartment = af.createAssociation(associationEnds);
		
		// Create association between employee and company with associative class Work
		AssociationClassFacade acf = new AssociationClassFacade(p);
		
			// These are the association ends
		Property companyEnd2 = pf.createProperty();
		Property employeeEnd = pf.createProperty();
		companyEnd2.setType(company);
		companyEnd2.setName("employer");
		employeeEnd.setType(employee);
		employeeEnd.setName("employee");
		
			// Create and set the multiplicity 0..* to Company end
		LiteralInteger lowermultiplicity3 = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity3 = lif.createLiteralInteger();
		lowermultiplicity3.setValue(0);
		lowermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity3.setValue(-1);
		uppermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		companyEnd2.setLowerValue(lowermultiplicity3);
		companyEnd2.setUpperValue(uppermultiplicity3);
		
			// Create and set the multiplicity 1..* to Employee end
		LiteralInteger lowermultiplicity4 = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity4 = lif.createLiteralInteger();
		lowermultiplicity4.setValue(1);
		lowermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity4.setValue(-1);
		uppermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		employeeEnd.setLowerValue(lowermultiplicity4);
		employeeEnd.setUpperValue(uppermultiplicity4);
		
		LinkedList associationEnds2 = new LinkedList();
		associationEnds2.add(companyEnd2);
		associationEnds2.add(employeeEnd);
		AssociationClass work = acf.createAssociationClass(associationEnds2);
		work.setName("Work");
		
		// Create the owned elements of Work associative class
		Property years = pf.createProperty();
		Property range = pf.createProperty();
		years.setName("years");
		years.setType(integer);
		years.setUmlclass(work);
		range.setName("range");
		range.setType(string);
		range.setUmlclass(work);
		
		// Store the conceptual schema into an XMI file
		p.saveXMI("/Users/lotendil/Desktop/save.xmi");
		p.closeProject();
		
	}

}